from celery import current_app
from flask import (
    Blueprint,
    jsonify,
    send_file,
    request,
    abort,
    make_response,
    redirect,
    url_for,
)
from datetime import date, datetime, timedelta
import io
import pandas as pd
import zipfile
from .models import (
    ScheduleResult,
    Elderdemand,
    TimeSlot,
    DicNursingAction,
    Attendantskills,
    CaregiverSchedule,
    ShiftAssignment,
    db,
)
from .scheduler import Plan
from .three_shift import ThreeShiftScheduler
from config_params import params
from sqlalchemy import func
from .redis_utils import get_redis_connection
from .redis_utils import get_update_time

main = Blueprint("main", __name__)


@main.route("/")
def index():
    return "Welcome to the Nursing Schedule App!"


@main.route("/check_update", methods=["GET"])
def check_update():
    redis_conn = get_redis_connection()
    if redis_conn:
        update_value = redis_conn.get(current_app.config["REDIS_UPDATE_KEY"])
        return jsonify({"update": update_value})
    else:
        return jsonify({"error": "无法连接到Redis"}), 500


@main.route("/last_update_time", methods=["GET"])
def get_last_update_time():
    last_update_time = get_update_time()
    if last_update_time:
        return jsonify({"last_update_time": last_update_time})
    else:
        return jsonify({"error": "无法获取最后更新时间"}), 404


@main.route("/generate_and_save_schedule", methods=["GET", "POST"])
def generate_and_save_schedule():
    plan = Plan(params)
    plan.run()  # 运行排班算法并保存结果

    if request.method == "POST":
        return jsonify(
            {
                "message": "Schedules generated and saved successfully",
                "date": datetime.now().isoformat(),
            }
        )
    else:
        return redirect(url_for("main.view_schedule"))


@main.route("/caregiver_schedule/<string:caregiver_id>", methods=["GET"])
def get_caregiver_schedule(caregiver_id):
    schedule_date_str = request.args.get("date", date.today().isoformat())
    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()

    schedules = (
        CaregiverSchedule.query.filter(
            CaregiverSchedule.caregiver_id == caregiver_id,
            func.date(CaregiverSchedule.schedule_date) == schedule_date,
        )
        .order_by(CaregiverSchedule.time_slot)
        .all()
    )

    return jsonify(
        [
            {"time_slot": schedule.time_slot, "is_available": schedule.is_available}
            for schedule in schedules
        ]
    )


@main.route("/update_caregiver_availability", methods=["POST"])
def update_caregiver_availability():
    data = request.json
    caregiver_id = data.get("caregiver_id")
    schedule_date_str = data.get("date")
    time_slot = data.get("time_slot")
    is_available = data.get("is_available")

    if not all(
        [
            caregiver_id,
            schedule_date_str,
            time_slot is not None,
            is_available is not None,
        ]
    ):
        return jsonify({"error": "Missing required data"}), 400

    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()

    schedule = CaregiverSchedule.query.filter_by(
        caregiver_id=caregiver_id, schedule_date=schedule_date, time_slot=time_slot
    ).first()

    if schedule:
        schedule.is_available = is_available
    else:
        new_schedule = CaregiverSchedule(
            caregiver_id=caregiver_id,
            schedule_date=schedule_date,
            time_slot=time_slot,
            is_available=is_available,
        )
        db.session.add(new_schedule)

    try:
        db.session.commit()
        return jsonify({"message": "Caregiver availability updated successfully"}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": str(e)}), 500


@main.route("/view_schedule", methods=["GET"])
def view_schedule():
    elder = request.args.get("elder")
    schedule_date_str = request.args.get("date", date.today().isoformat())
    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()

    def process_time_slot(ts):
        return {
            "id": ts.id,
            "elder": ts.elder,
            "time_slot": ts.time_slot,
            "activity": ts.activity,
            "activity_id": ts.activity_id,
            "caregiver": "lack" if ts.caregiver_id == "-1" else ts.caregiver,
            "caregiver_id": ts.caregiver_id,
            "schedule_date": ts.schedule_date.isoformat(),
        }

    try:
        if elder:
            schedule_result = ScheduleResult.query.filter(
                ScheduleResult.elder == elder,
                db.func.date(ScheduleResult.schedule_date) == schedule_date,
            ).first()
            if schedule_result:
                time_slots = (
                    TimeSlot.query.filter_by(schedule_result_id=schedule_result.id)
                    .order_by(TimeSlot.time_order)
                    .all()
                )
                return jsonify(
                    {
                        "elder": elder,
                        "schedule_date": schedule_date.isoformat(),
                        "json_data": schedule_result.schedule_data,
                        "time_slots": [process_time_slot(ts) for ts in time_slots],
                    }
                )
            else:
                return jsonify({"error": "Schedule not found"}), 404
        else:
            all_schedules = ScheduleResult.query.filter(
                db.func.date(ScheduleResult.schedule_date) == schedule_date
            ).all()
            grouped_schedules = {}
            for sr in all_schedules:
                elder = sr.elder
                time_slots = (
                    TimeSlot.query.filter_by(schedule_result_id=sr.id)
                    .order_by(TimeSlot.time_order)
                    .all()
                )
                grouped_schedules[elder] = {
                    "schedule_date": sr.schedule_date.isoformat(),
                    "json_data": sr.schedule_data,
                    "time_slots": [process_time_slot(ts) for ts in time_slots],
                }
            return jsonify(grouped_schedules)
    except Exception as e:
        return jsonify({"error": str(e)}), 500


@main.route("/download_schedule/<string:elder>", methods=["GET"])
def download_schedule(elder):
    schedule_date_str = request.args.get("date", date.today().isoformat())
    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()

    schedule_result = ScheduleResult.query.filter(
        ScheduleResult.elder == elder,
        func.date(ScheduleResult.schedule_date) == schedule_date,
    ).first()

    if not schedule_result:
        abort(404, description="Schedule not found")

    time_slots = (
        TimeSlot.query.filter_by(schedule_result_id=schedule_result.id)
        .order_by(TimeSlot.time_order)
        .all()
    )

    df = pd.DataFrame(
        [
            (
                ts.time_slot,
                ts.elder,
                ts.activity,
                ts.activity_id,
                "lack" if ts.caregiver_id == "-1" else ts.caregiver,
                ts.caregiver_id,
                ts.schedule_date,
            )
            for ts in time_slots
        ],
        columns=[
            "TimeSlot",
            "Elder",
            "Activity",
            "ActivityId",
            "Caregiver",
            "CaregiverId",
            "ScheduleDate",
        ],
    )

    excel_buffer = io.BytesIO()
    df.to_excel(excel_buffer, index=False)
    excel_buffer.seek(0)

    return send_file(
        excel_buffer,
        mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        as_attachment=True,
        download_name=f"{elder}_schedule_{schedule_date.isoformat()}.xlsx",
    )


@main.route("/download_all_schedules", methods=["GET"])
def download_all_schedules():
    schedule_date_str = request.args.get("date", date.today().isoformat())
    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()
    schedule_results = ScheduleResult.query.filter(
        db.func.date(ScheduleResult.schedule_date) == schedule_date
    ).all()

    if not schedule_results:
        abort(404, description="No schedules found for the specified date")

    memory_file = io.BytesIO()
    with zipfile.ZipFile(memory_file, "w") as zf:
        for schedule_result in schedule_results:
            time_slots = (
                TimeSlot.query.filter_by(schedule_result_id=schedule_result.id)
                .order_by(TimeSlot.time_order)
                .all()
            )
            df = pd.DataFrame(
                [
                    (
                        ts.time_slot,
                        ts.activity,
                        "lack" if ts.caregiver_id == "-1" else ts.caregiver,
                    )
                    for ts in time_slots
                ],
                columns=["TimeSlot", "Activity", "Caregiver"],
            )
            excel_buffer = io.BytesIO()
            df.to_excel(excel_buffer, index=False)
            excel_buffer.seek(0)
            zf.writestr(
                f"{schedule_result.elder}_schedule.xlsx", excel_buffer.getvalue()
            )

    memory_file.seek(0)

    return send_file(
        memory_file,
        mimetype="application/zip",
        as_attachment=True,
        download_name=f"all_schedules_{schedule_date.isoformat()}.zip",
    )


@main.route("/nursing_actions", methods=["GET"])
def get_nursing_actions():
    actions = DicNursingAction.query.all()
    return jsonify(
        [
            {
                "id": action.id,
                "pid": action.pid,
                "name": action.name,
                "level": action.level,
                "nursing_level": action.nursing_level,
            }
            for action in actions
        ]
    )


@main.route("/elders", methods=["GET"])
def get_elders():
    elders = Elderdemand.query.filter_by(arrange="1").all()  # 只返回arrange为'1'的老人
    return jsonify(
        [
            {
                "id": elder.id,
                "elder": elder.elder,
                "actions": elder.actions,
                "arrange": elder.arrange,
            }
            for elder in elders
        ]
    )


@main.route("/caregivers", methods=["GET"])
def get_caregivers():
    caregivers = Attendantskills.query.all()
    return jsonify(
        [
            {
                "id": caregiver.id,
                "attendant_name": caregiver.attendant_name,
                "skills": caregiver.skills,
            }
            for caregiver in caregivers
        ]
    )


# 自动排班相关函数已完全移除
# 自动排班控制接口已完全移除


# 手动触发自动排班
@main.route("/auto_schedule_once", methods=["POST"])
def auto_schedule_once():
    """一次性执行自动排班，不启动后台线程"""
    try:
        start_time = datetime.now()
        data = request.json or {}

        # 获取请求参数
        days = int(data.get("days", 1))
        start_date = data.get("start_date")
        shift_mode = data.get("shift_mode", "three_shift")
        custom_shifts = data.get("custom_shifts")
        time_slots_per_day = int(data.get("time_slots_per_day", 72))
        time_interval_minutes = int(data.get("time_interval_minutes", 20))

        # 验证参数
        if days < 1 or days > 365:
            return jsonify({"error": "排班天数必须在1到365之间"}), 400

        # 如果没有提供开始日期，使用当前日期
        if not start_date:
            start_date = datetime.now().strftime("%Y-%m-%d")

        # 验证日期格式
        try:
            datetime.strptime(start_date, "%Y-%m-%d")
        except ValueError:
            return jsonify({"error": "日期格式无效，请使用YYYY-MM-DD格式"}), 400

        # 记录请求信息
        import logging

        logger = logging.getLogger("auto_schedule_once")
        logger.info(
            f"收到自动排班请求: 天数={days}, 开始日期={start_date}, 班制模式={shift_mode}"
        )

        # 创建调度器
        scheduler = ThreeShiftScheduler()

        # 如果提供了班制模式，设置班制模式
        if shift_mode:
            scheduler.set_shift_mode(mode=shift_mode, custom_shifts=custom_shifts)

        # 执行排班
        results = []
        total_shift_assignments = 0
        total_schedule_results = 0
        total_time_slots = 0

        # 循环生成指定天数的排班
        for i in range(days):
            # 计算当前日期
            if i > 0:
                current_date = (
                    datetime.strptime(start_date, "%Y-%m-%d") + timedelta(days=i)
                ).strftime("%Y-%m-%d")
            else:
                current_date = start_date

            logger.info(f"正在生成第 {i+1}/{days} 天的排班，日期: {current_date}")

            # 生成排班
            result = scheduler.generate_and_save_schedule(
                start_date=current_date,
                generate_care_timeline=True,
                shift_mode=shift_mode,
                custom_shifts=custom_shifts,
                time_slots_per_day=time_slots_per_day,
                time_interval_minutes=time_interval_minutes,
            )

            # 累计统计数据
            if result.get("success"):
                total_shift_assignments += result.get("shift_assignments_count", 0)
                total_schedule_results += result.get("schedule_results_count", 0)
                total_time_slots += result.get("time_slots_count", 0)

            # 添加到结果列表
            results.append({"date": current_date, "result": result})

        # 计算总耗时
        end_time = datetime.now()
        duration = (end_time - start_time).total_seconds()

        # 返回结果
        return jsonify(
            {
                "success": True,
                "message": f"成功生成 {days} 天的排班计划",
                "start_time": start_time.isoformat(),
                "end_time": end_time.isoformat(),
                "duration": f"{duration:.2f} 秒",
                "total_shift_assignments": total_shift_assignments,
                "total_schedule_results": total_schedule_results,
                "total_time_slots": total_time_slots,
                "results": results,
            }
        )
    except Exception as e:
        import traceback

        logger.error(f"自动排班出错: {str(e)}\n{traceback.format_exc()}")
        return jsonify({"error": str(e)}), 500


# 自动排班触发接口已完全移除


@main.route("/three_shift_schedule", methods=["POST"])
def generate_three_shift_schedule():
    """生成三班制排班计划API"""
    try:
        # 记录请求内容
        import logging

        logger = logging.getLogger(__name__)
        logger.info(f"接收到三班制排班请求: {request.data}")

        # 尝试解析JSON
        try:
            if request.data:
                data = request.get_json(force=True)
                logger.info(f"成功解析JSON数据: {data}")
            else:
                data = {}
                logger.warning("请求体为空，使用默认参数")
        except Exception as json_error:
            logger.error(f"JSON解析错误: {str(json_error)}")
            # 当JSON解析失败时，使用空字典继续执行
            data = {}
            logger.warning("由于JSON解析错误，使用默认参数继续执行")

        # 使用全局参数作为默认值
        from config_params import three_shift_params

        # 获取请求参数（如果提供，则覆盖全局参数）
        schedule_type = data.get(
            "schedule_type", three_shift_params.get("schedule_type", 1)
        )
        num_days = int(data.get("num_days", three_shift_params.get("num_days", 1)))
        start_date = data.get("start_date", three_shift_params.get("start_date"))
        shift_start_time = data.get(
            "shift_start_time", three_shift_params.get("shift_start_time")
        )

        # 班制控制参数
        shift_mode = data.get("shift_mode")  # 班制模式
        custom_shifts = data.get("custom_shifts")  # 自定义班次
        enabled_shifts = data.get("enabled_shifts")  # 启用的班次
        disabled_shifts = data.get("disabled_shifts")  # 禁用的班次
        auto_adjust_time = data.get("auto_adjust_time")  # 是否自动调整班次时间

        # 休息时间控制参数
        min_rest_between_shifts = data.get(
            "min_rest_between_shifts"
        )  # 班次间最小休息时间
        min_rest_after_night_shift = data.get(
            "min_rest_after_night_shift"
        )  # 夜班后最小休息时间
        max_consecutive_shifts = data.get(
            "max_consecutive_shifts"
        )  # 最大连续工作班次数

        # 验证排班类型
        valid_schedule_types_str = ["daily", "weekly", "monthly", "quarterly", "yearly"]
        valid_schedule_types_int = [1, 2, 3, 4, 5]

        # 如果是字符串类型
        if (
            isinstance(schedule_type, str)
            and schedule_type not in valid_schedule_types_str
        ):
            return (
                jsonify(
                    {
                        "error": f"不支持的排班类型: {schedule_type}。支持的类型: {', '.join(valid_schedule_types_str)}"
                    }
                ),
                400,
            )
        # 如果是数字类型
        elif (
            isinstance(schedule_type, int)
            and schedule_type not in valid_schedule_types_int
        ):
            return (
                jsonify(
                    {
                        "error": f"不支持的排班类型数字: {schedule_type}。支持的类型: 1(按天), 2(按周), 3(按月), 4(按季度), 5(按年)"
                    }
                ),
                400,
            )

        # 将数字类型转换为字符串类型（与原有代码兼容）
        schedule_type_map = {
            1: "daily",
            2: "weekly",
            3: "monthly",
            4: "quarterly",
            5: "yearly",
        }

        # 如果是数字类型，转换为字符串
        if isinstance(schedule_type, int):
            schedule_type = schedule_type_map.get(schedule_type)

        # 验证天数参数（仅当排班类型为daily时需要）
        if schedule_type == "daily" and (num_days < 1 or num_days > 365):
            return jsonify({"error": "天数参数必须在1到365之间"}), 400

        # 验证开始日期格式
        if start_date:
            try:
                datetime.strptime(start_date, "%Y-%m-%d")
            except ValueError:
                return jsonify({"error": "开始日期格式无效，请使用YYYY-MM-DD格式"}), 400

        # 验证班次开始时间格式
        if shift_start_time:
            try:
                datetime.strptime(shift_start_time, "%H:%M")
            except ValueError:
                return jsonify({"error": "班次开始时间格式无效，请使用HH:MM格式"}), 400

        # 实例化三班制排班调度器
        scheduler = ThreeShiftScheduler()

        # 如果提供了班制模式，设置班制模式
        if shift_mode:
            scheduler.set_shift_mode(
                mode=shift_mode,
                custom_shifts=custom_shifts,
                start_time=shift_start_time,
            )

        # 如果提供了启用班次列表，更新班次配置
        if enabled_shifts:
            scheduler.update_shift_config(enabled_shifts=enabled_shifts)

        # 如果提供了禁用班次列表，设置禁用班次
        if disabled_shifts:
            scheduler.disable_shifts(disabled_shifts)

        # 如果提供了自动调整时间参数，更新班次控制参数
        if auto_adjust_time is not None:
            scheduler.update_shift_control(auto_adjust_time=auto_adjust_time)

        # 如果提供了休息时间控制参数，更新休息时间控制参数
        if (
            min_rest_between_shifts is not None
            or min_rest_after_night_shift is not None
            or max_consecutive_shifts is not None
        ):
            # 更新休息时间控制参数
            if min_rest_between_shifts is not None:
                scheduler.rest_time_control["min_rest_between_shifts"] = (
                    min_rest_between_shifts
                )

            if min_rest_after_night_shift is not None:
                scheduler.rest_time_control["min_rest_after_night_shift"] = (
                    min_rest_after_night_shift
                )

            if max_consecutive_shifts is not None:
                scheduler.rest_time_control["max_consecutive_shifts"] = (
                    max_consecutive_shifts
                )

        # 生成并保存排班计划
        logger.info(
            f"开始生成排班计划: schedule_type={schedule_type}, num_days={num_days}, start_date={start_date}"
        )

        # 添加generate_care_timeline参数
        generate_care_timeline = data.get(
            "generate_care_timeline",
            three_shift_params.get("generate_care_timeline", True),
        )
        logger.info(f"是否生成照护时间线: {generate_care_timeline}")

        result = scheduler.generate_and_save_schedule(
            schedule_type=schedule_type,  # 已经在前面转换为字符串类型
            num_days=num_days,
            start_date=start_date,
            shift_start_time=shift_start_time,
            generate_care_timeline=generate_care_timeline,
            shift_mode=shift_mode,
            custom_shifts=custom_shifts,
            time_slots_per_day=72,  # 一天分为72个时间段
            time_interval_minutes=20,  # 每个时间段为20分钟
        )

        logger.info(f"排班计划生成结果: {result}")

        return jsonify(result)
    except Exception as e:
        import traceback

        error_traceback = traceback.format_exc()
        logger.error(f"排班计划生成失败: {str(e)}")
        logger.error(f"错误详情: {error_traceback}")
        return (
            jsonify(
                {
                    "error": str(e),
                    "traceback": (
                        error_traceback.split("\n") if error_traceback else None
                    ),
                }
            ),
            500,
        )


@main.route("/three_shift_schedule", methods=["GET"])
def get_three_shift_schedule():
    """获取三班制排班计划API"""
    try:
        # 获取请求参数
        start_date_str = request.args.get("start_date")
        end_date_str = request.args.get("end_date")
        caregiver_id = request.args.get("caregiver_id")

        # 处理日期参数
        if start_date_str:
            try:
                start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date()
            except ValueError:
                return jsonify({"error": "开始日期格式无效，请使用YYYY-MM-DD格式"}), 400
        else:
            # 默认为今天
            start_date = date.today()

        if end_date_str:
            try:
                end_date = datetime.strptime(end_date_str, "%Y-%m-%d").date()
            except ValueError:
                return jsonify({"error": "结束日期格式无效，请使用YYYY-MM-DD格式"}), 400
        else:
            # 默认为今天
            end_date = start_date

        # 验证日期范围
        if end_date < start_date:
            return jsonify({"error": "结束日期不能早于开始日期"}), 400

        # 查询排班数据
        if caregiver_id:
            # 查询特定护理员的排班，日期降序排序
            assignments = ShiftAssignment.get_assignments_by_caregiver(
                caregiver_id, start_date, end_date, date_desc=True
            )
        else:
            # 查询所有排班，日期降序排序
            assignments = ShiftAssignment.get_assignments_by_date_range(
                start_date, end_date, date_desc=True
            )

        # 构建响应数据
        result = {
            "start_date": start_date.isoformat(),
            "end_date": end_date.isoformat(),
            "total_assignments": len(assignments),
            "assignments": [],
        }

        for assignment in assignments:
            result["assignments"].append(
                {
                    "id": assignment.id,
                    "caregiver_id": assignment.caregiver_id,
                    "caregiver_name": assignment.caregiver_name,
                    "shift_date": assignment.shift_date.isoformat(),
                    "shift_type": assignment.shift_type,
                    "shift_start_time": assignment.shift_start_time.strftime("%H:%M"),
                    "shift_end_time": assignment.shift_end_time.strftime("%H:%M"),
                    "schedule_type": assignment.schedule_type,
                }
            )

        return jsonify(result)
    except Exception as e:
        return jsonify({"error": str(e)}), 500


@main.route("/elder_schedule/<string:elder_id>", methods=["GET"])
def get_elder_schedule(elder_id):
    """获取老人的详细排班信息"""
    try:
        # 获取请求参数
        date_str = request.args.get("date", date.today().isoformat())

        # 处理日期参数
        try:
            schedule_date = datetime.strptime(date_str, "%Y-%m-%d").date()
        except ValueError:
            return jsonify({"error": "日期格式无效，请使用YYYY-MM-DD格式"}), 400

        # 查询老人的排班结果
        schedule_result = ScheduleResult.query.filter_by(
            elder=elder_id, schedule_date=schedule_date
        ).first()

        if not schedule_result:
            return (
                jsonify({"error": f"未找到老人 {elder_id} 在 {date_str} 的排班信息"}),
                404,
            )

        # 查询时间段安排
        time_slots = (
            TimeSlot.query.filter_by(schedule_result_id=schedule_result.id)
            .order_by(TimeSlot.time_order)
            .all()
        )

        # 构建响应数据
        result = {
            "elder_id": elder_id,
            "schedule_date": schedule_date.isoformat(),
            "schedule_data": schedule_result.schedule_data,
            "time_slots": [],
        }

        for slot in time_slots:
            result["time_slots"].append(
                {
                    "time_slot": slot.time_slot,
                    "activity": slot.activity,
                    "activity_id": slot.activity_id,
                    "caregiver": slot.caregiver,
                    "caregiver_id": slot.caregiver_id,
                    "time_order": slot.time_order,
                }
            )

        return jsonify(result)
    except Exception as e:
        return jsonify({"error": str(e)}), 500


@main.route("/download_three_shift_schedule", methods=["GET"])
def download_three_shift_schedule():
    """下载三班制排班计划"""
    try:
        # 获取请求参数
        start_date_str = request.args.get("start_date")
        end_date_str = request.args.get("end_date")

        # 处理日期参数
        if start_date_str:
            try:
                start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date()
            except ValueError:
                return jsonify({"error": "开始日期格式无效，请使用YYYY-MM-DD格式"}), 400
        else:
            # 默认为今天
            start_date = date.today()

        if end_date_str:
            try:
                end_date = datetime.strptime(end_date_str, "%Y-%m-%d").date()
            except ValueError:
                return jsonify({"error": "结束日期格式无效，请使用YYYY-MM-DD格式"}), 400
        else:
            # 默认为今天
            end_date = start_date

        # 验证日期范围
        if end_date < start_date:
            return jsonify({"error": "结束日期不能早于开始日期"}), 400

        # 查询排班数据
        assignments = ShiftAssignment.get_assignments_by_date_range(
            start_date, end_date
        )

        if not assignments:
            return jsonify({"error": "指定日期范围内没有排班数据"}), 404

        # 创建DataFrame
        data = []
        for a in assignments:
            data.append(
                {
                    "护理员ID": a.caregiver_id,
                    "护理员姓名": a.caregiver_name,
                    "排班日期": a.shift_date.isoformat(),
                    "班次类型": a.shift_type,
                    "开始时间": a.shift_start_time.strftime("%H:%M"),
                    "结束时间": a.shift_end_time.strftime("%H:%M"),
                    "排班类型": a.schedule_type,
                }
            )

        df = pd.DataFrame(data)

        # 生成Excel文件
        excel_buffer = io.BytesIO()
        df.to_excel(excel_buffer, index=False)
        excel_buffer.seek(0)

        return send_file(
            excel_buffer,
            mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            as_attachment=True,
            download_name=f"three_shift_schedule_{start_date.isoformat()}_to_{end_date.isoformat()}.xlsx",
        )
    except Exception as e:
        return jsonify({"error": str(e)}), 500


@main.errorhandler(404)
def not_found(error):
    return make_response(jsonify({"error": str(error)}), 404)


def init_app(app):
    app.register_blueprint(main)

    # 通过POST请求到 /generate_and_save_schedule  生成新的调度并保存到数据库。
    # 通过GET请求到 /view_schedule查看保存的调度。
    # 通过GET请求到 /download_all_schedules或 /download_schedule/<elder_id> 下载保存的调度。

    # 照护计划id
    # 老人id
    # 时间段
    # 护理动作
    # 护理员
    # 更新时间
